#ifndef LUACALLBACKS_H
#define LUACALLBACKS_H

#include <iostream>
#include "gamestate.h"
#include "simulation.h"

#include "entities/army.h"
#include "entities/city.h"
#include "entities/tile.h"

extern "C" {
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}

// void | cityID, value
static int SetMaxFarmDistance(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    float value = (float)lua_tonumber(L, 2);
//    std::shared_ptr<City> city = std::static_pointer_cast<City>(gamestate->GetImprovement(id));
//    if(city){
//        city->SetMaxFarmDistanceFromWater(value);
//    }
//    else{
//        std::cout<<"SetMaxFarmDistance Error: invalid city\n";
//    }
    return 0;
}

// container | contained
static int GetContainingEntity(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    int entID;
//    std::shared_ptr<Entity> ent = gamestate->GetEntity(id);
//    if(ent!=nullptr){
//        entID = ent->ContainingEntity();
//    }
//    else{
//        std::cout<<"GetContainingEntity Error: invalid entity: "<<id<<std::endl;
//        entID = 0;
//    }
//    lua_pushnumber(L, entID);
    return 1;
}

static int GetPopulation(lua_State* L){
//    int id = (int)lua_tonumber(L,1)-1;
//    lua_pushnumber(L, gamestate->GetImprovement(id)->Population());
    return 1;
}

static int GetGrowthFactor(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    float growth = (float)lua_tonumber(L, 2);
//    std::shared_ptr<City> city = std::static_pointer_cast<City>(gamestate->GetImprovement(id));
//    if(city==nullptr){
//        std::cout<<"AddGrowthFactor Error: Invalid City: "<<id<<std::endl;
//    }
//    else{
//        city->AddGrowthFactor(growth);
//    }
    return 0;
}

static int GetCityOwner(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    int city;
//    std::shared_ptr<Entity> entity = gamestate->GetEntity(id);
//    if(entity==nullptr){
//        std::cout<<"GetCityOwner Error: Invalid Entity: "<<id<<std::endl;
//        city = -1;
//    }
//    else{
//        city = entity->GetCityOwner();
//    }
//    lua_pushnumber(L, city);
    return 1;
}

static int GetOwner(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    int owner;
//    std::shared_ptr<Entity> entity = gamestate->GetEntity(id);
//    if(entity==nullptr){
//        std::cout<<"GetOwner Error: Invalid Entity: "<<id<<std::endl;
//        owner = -1;
//    }
//    else{
//        owner = entity->GetOwner();
//    }
//    lua_pushnumber(L, owner);
    return 1;
}

static int GetIndex(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    int index;
//    std::shared_ptr<Entity> entity = gamestate->GetEntity(id);
//    if(entity==nullptr){
//        std::cout<<"GetIndex Error: Invalid Entity: "<<id<<std::endl;
//        index = -1;
//    }
//    else{
//        index = entity->GetIndex();
//    }
//    lua_pushnumber(L, index);
    return 1;
}

// Variables ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int AddIntVar(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    std::string name = lua_tostring(L, 2);
//    int value = (int)lua_tonumber(L, 3);
//    std::shared_ptr<Entity> entity = gamestate->GetEntity(id);
//
//    if(entity==nullptr){
//        std::cout<<"CreateIntVar Error: Invalid Entity: "<<id<<std::endl;
//    }
//    else{
//        entity->AddIntVar(name, value);
//    }
    return 0;
}

static int SetIntVar(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    std::string name = lua_tostring(L, 2);
//    int value = (int)lua_tonumber(L, 3);
//    std::shared_ptr<Entity> entity = gamestate->GetEntity(id);
//
//    if(entity==nullptr){
//        std::cout<<"SetIntVar Error: Invalid Entity: "<<id<<std::endl;
//    }
//    else{
//        entity->SetIntVar(name, value);
//    }
    return 0;
}

static int GetIntVar(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    std::string name = lua_tostring(L, 2);
//    int value;
//    std::shared_ptr<Entity> entity = gamestate->GetEntity(id);
//
//    if(entity==nullptr){
//        std::cout<<"GetIntVar Error: Invalid Entity: "<<id<<std::endl;
//        value = -1;
//    }
//    else{
//        value = entity->GetIntVar(name);
//    }
//    lua_pushnumber(L, value);
    return 1;
}

// Constructions and upgrades //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int AddConstructionOption(lua_State* L){
//    std::cout<<"AddConstructionOption\n";
//    int id = (int)lua_tonumber(L, 1);
//    std::string name = lua_tostring(L, 2);
//    std::shared_ptr<Improvement> improvement = gamestate->GetImprovement(id);
//    if(improvement==nullptr){
//        std::cout<<"AddToConstructions Error: Invalid Entity: "<<id<<std::endl;
//        return 0;
//    }
//    improvement->AddConstructionOption(name);
    return 0;
}

// Modifying improvements //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
static int DeleteImprovement(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    gamestate->DeleteImprovement(id);
    return 0;
}

// input: index, owner
// output: cityID
static int CreateCity(lua_State* L){
//    int index = (int)lua_tonumber(L, 1);
//    int owner = (int)lua_tonumber(L, 2);
//    std::shared_ptr<City> city;
//
//    city = simulation->FoundCity(index, owner);
//    lua_pushnumber(L, city->GetID());
    return 1;
}

// input: unitID
// output: none
static int DeleteUnit(lua_State* L){
//    int id = (int)lua_tonumber(L, 1);
//    Entity* container = gamestate->GetEntityContainingUnit(id);
//
//    gamestate->DeleteUnit(id);
//    container->RemoveFromUnits(id);
    return 0;
}

// input: armyID, garrisonID
// output: none
static int GarrisonArmy(lua_State* L){
//    int armyID = (int)lua_tonumber(L, 1);
//    int garrisonID = (int)lua_tonumber(L, 2);
//    std::cout<<"ArmyID: "<<armyID<<std::endl;
//    std::vector<int> unitIDs = gamestate->GetArmy(armyID)->GetUnitIDs();
//
//    if(gamestate->DeleteArmy(armyID)==false){
//        std::cout<<"GarrisonArmy Error: Couldn't delete army: "<<armyID<<std::endl;
//    }
//    gamestate->GetEntity(garrisonID)->AddToUnits(unitIDs);
    return 0;
}

// input: tileID
// output: [food, coin, production, owner, improvement]
static int GetTileInfo(lua_State* L){
//    int tileID = (int)lua_tonumber(L, 1);
//    std::shared_ptr<Tile> tile = gamestate->GetTileByID(tileID);
//
//    lua_newtable(L);
//    int top = lua_gettop(L);
//
//    if(tile==nullptr){
//        std::cout<<"Tile id invalid"<<std::endl;
//        return 1;
//    }
//
//    lua_pushstring(L, "owner");
//    lua_pushnumber(L, tile->GetOwner());
//    lua_settable(L, top);
//
//    lua_pushstring(L, "improvement");
//    lua_pushnumber(L, tile->GetImprovement());
//    lua_settable(L, top);
    return 1;
}

// input: unitID
// output: [position, owner, container]
static int GetUnitInfo(lua_State* L){
//    int unitID = (int)lua_tonumber(L, 1);
//    Unit* unit = gamestate->GetUnit(unitID);
//    Entity* container = gamestate->GetEntityContainingUnit(unitID);
//
//    lua_newtable(L);
//    int top = lua_gettop(L);
//
//    if(unit==nullptr){
//        std::cout<<"Unit id invalid"<<std::endl;
//        return 1;
//    }
//    if(container==nullptr){
//        std::cout<<"Unit is not in an army or garrison"<<std::endl;
//        return 1;
//    }
//
//    lua_pushstring(L, "position");
//    lua_pushnumber(L, container->GetPosition());
//    lua_settable(L, top);
//    lua_pushstring(L, "owner");
//    lua_pushnumber(L, container->GetOwner());
//    lua_settable(L, top);
//    lua_pushstring(L, "container");
//    lua_pushnumber(L, container->GetID());
//    lua_settable(L, top);
    return 1;
}


#endif





